<template>
  <Form
    ref="formRef"
    :model="modelValue"
    :label-width="config.labelWidth"
    :label-position="config.labelPosition"
    :rules="rules"
    :show-message="true"
    :label-colon="config.labelColon"
  >
    <FormItem
      v-for="(item, field) in fields"
      :key="field"
      :label="item.label"
      :prop="field"
      v-show="!item.hidden"
    >
      <!-- 输入框 -->
      <Input
        v-if="item.type === 'input'"
        v-model="modelValue[field]"
        :placeholder="item.placeholder || '请输入' + item.label"
        :disabled="item.disabled"
        :clearable="item.clearable"
        :maxlength="item.maxlength"
        :show-word-limit="item.showWordLimit"
        :type="item.inputType || 'text'"
      />

      <!-- 文本域 -->
      <Input
        v-else-if="item.type === 'textarea'"
        v-model="modelValue[field]"
        type="textarea"
        :placeholder="item.placeholder || '请输入' + item.label"
        :disabled="item.disabled"
        :clearable="item.clearable"
        :maxlength="item.maxlength"
        :show-word-limit="item.showWordLimit"
        :rows="item.rows || 4"
      />

      <!-- 数字输入框 -->
      <InputNumber
        v-else-if="item.type === 'number'"
        v-model="modelValue[field]"
        :placeholder="item.placeholder || '请输入' + item.label"
        :disabled="item.disabled"
        :max="item.max"
        :min="item.min"
        :precision="item.precision"
        :step="item.step || 1"
        style="width: 100%"
      />

      <!-- 下拉选择框 -->
      <Select
        v-else-if="item.type === 'select'"
        v-model="modelValue[field]"
        :placeholder="item.placeholder || '请选择' + item.label"
        :disabled="item.disabled"
        :clearable="item.clearable"
        :multiple="item.multiple"
        :filterable="item.filterable"
        :transfer="item.transfer"
        style="width: 100%"
      >
        <Option
          v-for="(option, optionIndex) in item.options"
          :key="optionIndex"
          :value="option.value"
          :label="option.label"
          :disabled="option.disabled"
        >
          {{ option.label }}
        </Option>
      </Select>

      <!-- 单选框组 -->
      <RadioGroup
        v-else-if="item.type === 'radio'"
        v-model="modelValue[field]"
        :disabled="item.disabled"
      >
        <Radio
          v-for="(option, optionIndex) in item.options"
          :key="optionIndex"
          :label="option.value"
          :disabled="option.disabled"
        >
          {{ option.label }}
        </Radio>
      </RadioGroup>

      <!-- 多选框组 -->
      <CheckboxGroup
        v-else-if="item.type === 'checkbox'"
        v-model="modelValue[field]"
        :disabled="item.disabled"
        @on-change="item.change"
      >
        <Checkbox
          v-for="(option, optionIndex) in item.options"
          :key="optionIndex"
          :label="option.value"
          :disabled="option.disabled"
        >
          {{ option.label }}
        </Checkbox>
      </CheckboxGroup>

      <!-- 开关 -->
      <Switch
        v-else-if="item.type === 'switch'"
        v-model="modelValue[field]"
        :disabled="item.disabled"
        :true-value="item.trueValue !== undefined ? item.trueValue : true"
        :false-value="item.falseValue !== undefined ? item.falseValue : false"
      />

      <!-- 日期选择器 -->
      <DatePicker
        v-else-if="item.type === 'date'"
        v-model="modelValue[field]"
        :type="item.dateType || 'date'"
        :placeholder="item.placeholder || '请选择' + item.label"
        :disabled="item.disabled"
        :clearable="item.clearable"
        style="width: 100%"
      />

      <!-- 日期范围选择器 -->
      <DatePicker
        v-else-if="item.type === 'daterange'"
        v-model="modelValue[field]"
        type="daterange"
        :placeholder="item.placeholder || '请选择' + item.label"
        :disabled="item.disabled"
        :clearable="item.clearable"
        style="width: 100%"
      />

      <!-- 时间选择器 -->
      <TimePicker
        v-else-if="item.type === 'time'"
        v-model="modelValue[field]"
        :placeholder="item.placeholder || '请选择' + item.label"
        :disabled="item.disabled"
        :clearable="item.clearable"
        style="width: 100%"
      />

      <!-- 时间范围选择器 -->
      <TimePicker
        v-else-if="item.type === 'timerange'"
        v-model="modelValue[field]"
        type="timerange"
        :placeholder="item.placeholder || '请选择' + item.label"
        :disabled="item.disabled"
        :clearable="item.clearable"
        style="width: 100%"
      />

      <!-- 自定义插槽 -->
      <slot
        v-else
        :name="field"
        :field="field"
        :item="item"
      ></slot>
    </FormItem>

    <!-- 表单按钮区域 -->
    <FormItem v-if="showButtons">
      <Button
        type="primary"
        @click="handleSubmit"
        :loading="submitLoading"
      >
        {{ submitText }}
      </Button>
      <Button
        v-if="showReset"
        style="margin-left: 8px"
        @click="handleReset"
      >
        {{ resetText }}
      </Button>
      <slot name="buttons"></slot>
    </FormItem>
  </Form>
</template>

<script setup>
import { ref, computed, watch, onMounted } from 'vue';

// 定义组件属性
const props = defineProps({
  // 表单数据，通过v-model绑定
  modelValue: {
    type: Object,
    required: true,
    default: () => ({})
  },
  // 表单字段配置
  fields: {
    type: Object,
    required: true,
    default: () => ({})
  },
  // 表单全局配置
  config: {
    type: Object,
    default: () => ({
      labelWidth: 80,
      labelPosition: 'right',
      labelColon: true
    })
  },
  // 是否显示按钮
  showButtons: {
    type: Boolean,
    default: false
  },
  // 是否显示重置按钮
  showReset: {
    type: Boolean,
    default: true
  },
  // 提交按钮文本
  submitText: {
    type: String,
    default: '提交'
  },
  // 重置按钮文本
  resetText: {
    type: String,
    default: '重置'
  },
  // 提交按钮加载状态
  submitLoading: {
    type: Boolean,
    default: false
  }
});

// 定义组件事件
const emit = defineEmits(['update:modelValue', 'submit', 'reset']);

// 表单引用
const formRef = ref(null);

// 表单验证规则
const rules = computed(() => {
  const rulesObj = {};

  // 遍历所有字段，生成验证规则
  Object.entries(props.fields).forEach(([field, item]) => {
    // 如果字段有自定义规则，使用自定义规则
    if (item.rules) {
      rulesObj[field] = item.rules;
    }
    // 如果字段是必填的，添加必填验证规则
    else if (item.required) {
      // 根据表单项类型设置不同的触发方式
      let trigger = 'blur';
      if (['select', 'radio', 'checkbox', 'date', 'daterange', 'time', 'timerange', 'switch'].includes(item.type)) {
        trigger = 'change';
      }

      rulesObj[field] = [
        {
          required: true,
          message: `${item.label}不能为空`,
          trigger: item.trigger || trigger
        }
      ];
    }
  });

  return rulesObj;
});

// 判断表单项是否可见
const isVisible = (field, item) => {
  if (!item.visibleOn) return true;

  try {
    // 使用Function构造函数创建一个函数，该函数可以访问modelValue
    const visibleFn = new Function('data', `return ${item.visibleOn}`);
    return visibleFn(props.modelValue);
  } catch (error) {
    console.error(`计算字段 ${field} 的可见性时出错:`, error);
    return true;
  }
};

// 提交表单
const handleSubmit = () => {
  if (!formRef.value) return;

  formRef.value.validate(valid => {
    if (valid) {
      emit('submit', props.modelValue);
    }
  });
};

// 重置表单
const handleReset = () => {
  if (!formRef.value) return;

  formRef.value.resetFields();
  emit('reset');
};

// 清除表单验证
const clearValidate = (fields) => {
  if (!formRef.value?.clearValidate) return;

  formRef.value.clearValidate(fields);
};

// 手动验证表单
const validate = () => {
  return new Promise((resolve, reject) => {
    if (!formRef.value) {
      reject(new Error('表单引用不存在'));
      return;
    }

    formRef.value.validate(valid => {
      if (valid) {
        resolve(props.modelValue);
      } else {
        reject(new Error('表单验证失败'));
      }
    });
  });
};

// 监听表单数据变化，清除验证状态
watch(
  () => props.modelValue,
  () => {
    if (formRef.value && typeof formRef.value.clearValidate === 'function') {
      setTimeout(() => {
        formRef.value.clearValidate();
      }, 0);
    }
  },
  { deep: true }
);

// 组件挂载时清除验证状态
onMounted(() => {
  if (formRef.value && typeof formRef.value.clearValidate === 'function') {
    setTimeout(() => {
      formRef.value.clearValidate();
    }, 100);
  }
});

// 暴露组件方法
defineExpose({
  validate,
  resetFields: handleReset,
  clearValidate,
  formRef
});
</script>

<style scoped>
/* 可以根据需要添加样式 */
</style>